'''
# 基本IO
import cv2
# 读取版本号
print(cv2.getVersionString())
# 读取图片
image = cv2.imread("opencv_logo.jpg")
# 打印图片的形状（高度，宽度，通道数）
print(image.shape)

cv2.imshow("image", image)
cv2.waitKey()  # 让窗口暂停
'''

'''
import cv2 #导包 opencv
print(cv2.getVersionString()) # 输出版本号
image = cv2.imread("opencv_logo.jpg") #输入图片路径。读取图片
print(image.shape) #输出图片的形状如：高、宽、通道数
cv2.imshow('image',image) #展示图片
cv2.waitKey() #暂停窗口
'''

'''
# 图像的颜色
import cv2

image = cv2.imread("opencv_logo.jpg")
# 颜色通道顺序：BGR


cv2.imshow("blue", image[:, :, 0])
cv2.imshow("green", image[:, :, 1])
cv2.imshow("red", image[:, :, 2])


# 彩色图片灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)

cv2.waitKey()
'''
'''
# 图像裁剪操作
import cv2

image = cv2.imread("opencv_logo.jpg")

crop = image[10:170, 40:200]# 10 40,为左上角坐标值。 170为高 200为宽

cv2.imshow("crop", crop)
cv2.waitKey()
'''

'''
# 实现绘图功能
import cv2
import numpy as np

# 创建黑色画布
image = np.zeros([300, 300, 3], dtype=np.uint8)

# 绘制线段（对象， 起点， 终点， 颜色， 粗细）
cv2.line(image, (100, 200), (250, 250), (255, 0, 0), 2)
# 绘制矩形（~，起点， 对角点， 颜色， 粗细）
cv2.rectangle(image, (30, 100), (60, 150), (0, 255, 0), 2)
# 绘制圆形（~，圆心， 半径， 颜色， 粗细）
cv2.circle(image, (150, 100), 20, (0, 0, 255), 3)
# 绘制字符串（~， 内容， 坐标， 字体格式序号， 缩放系数， 颜色， 粗细， 线条类型序号）
cv2.putText(image, "hello", (100, 50), 0, 1, (255, 255, 255), 2, 1)

cv2.imshow("image", image)
cv2.waitKey()
'''

'''
# 图形的滤波
import cv2

image = cv2.imread("plane.jpg")
# 使用高斯滤波器
gauss = cv2.GaussianBlur(image, (5, 5), 0)
# 使用均值滤波器
median = cv2.medianBlur(image, 5)

cv2.imshow("image", image)
cv2.imshow("gauss", gauss)
cv2.imshow("median", median)

cv2.waitKey()
'''

'''
高斯滤波（Gaussian Blur）和均值滤波（Mean Blur）都是图像处理中常用的平滑技术，它们用于减少图像噪声、模糊图像边缘或细节，以及进行图像预处理。
选择使用哪种滤波方法取决于具体的应用场景和需求。

均值滤波：
简单易实现，对所有像素的邻域内的像素值求平均。
对于去除随机噪声（如椒盐噪声）效果较好。
对图像的边缘和细节的模糊程度较高，可能导致图像质量下降。

高斯滤波：
使用高斯分布作为权重，对邻域内的像素进行加权平均。
对图像的边缘和细节的模糊程度较低，通常能更好地保留图像的结构信息。
实现相对复杂，需要计算高斯核的权重。

在实际应用中，高斯滤波通常更受欢迎，因为它在平滑图像的同时能更好地保留图像的边缘和细节。
然而，如果处理速度是一个关键因素，均值滤波由于其简单性可能会更快。此外，对于某些特定的噪声类型，均值滤波可能更有效。

在决定使用哪种滤波方法时，可以考虑以下因素：
图像内容：如果图像中包含重要的边缘信息，高斯滤波可能更合适。
噪声类型：如果主要是随机噪声，均值滤波可能更有效。
实现复杂度：如果需要快速实现，均值滤波可能更简单。
性能要求：如果对图像质量有较高要求，高斯滤波通常能提供更好的结果。

在某些情况下，也可以结合使用这两种滤波方法，或者尝试其他类型的滤波器，如双边滤波（Bilateral Filter），它在平滑图像的同时能更好地保留边缘。
'''

'''
# 图片特征的提取
import cv2

image = cv2.imread("opencv_logo.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 图片先灰度化

# 获取特征点 （对象， 最多的点数， 质量优度水平， 特征点之间的最小距离）
corners = cv2.goodFeaturesToTrack(gray, 500, 0.1, 10)
# 标记出每个点
for corner in corners:
    x, y = corner.ravel()
    cv2.circle(image, (int(x), int(y)), 3, (255, 0, 255), -1)# 绘制圆形（~，圆心， 半径， 颜色， 粗细）

cv2.imshow("corners", image)

cv2.waitKey()
# 可以发现，特征点主要都在图片的转角处
'''
'''

# 图片的模板匹配（以匹配扑克牌上的菱形为例）
import cv2
import numpy as np

image = cv2.imread("poker.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 选取匹配模板
template = gray[75:105, 235:265]
#cv2.imshow('template',template)

# 使用标准相关匹配算法——将待检测对象和模板都标准化再来计算匹配度
match = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
locations = np.where(match >= 0.9)  # 找出匹配系数大于0.9的匹配点

w, h = template.shape[0:2]
for p in zip(*locations[::-1]):  # 循环遍历每一个匹配点并画出矩形框标记
    x1, y1 = p[0], p[1]
    x2, y2 = x1 + w, y1 + h
    cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)

cv2.imshow("image", image)
cv2.waitKey()
'''

'''
# 图像的梯度（明暗变化）
import cv2

gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE)  # 直接读取为灰度图

# 使用拉普拉斯算子（检测边缘——梯度剧烈变化处）
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
# canny边缘检测（定义边缘为梯度区间）
# 梯度大于200 -> 变化足够强烈，确定是边缘
# 梯度小于100 -> 变化较为平缓，确定非边缘
# 梯度介于二者之间 -> 待定，看其是否与已知的边缘像素相邻
canny = cv2.Canny(gray, 100, 200)

cv2.imshow("gray", gray)
cv2.imshow("laplacian", laplacian)
cv2.imshow("canny", canny)

cv2.waitKey()
'''
'''

# 图片的阈值算法(二值化，将连续的灰度范围切割为白+黑)
import cv2

# 图片灰度二值化
gray = cv2.imread("bookpage.jpg", cv2.IMREAD_GRAYSCALE)
ret, binary = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
# 图片自适应二值化（划分区块二值化，效果更好）
binary_adaptive = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
# 大津算法（基于图片灰度聚类分析，自定义阈值）
ret1, binary_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.imshow("adaptive", binary_adaptive)
cv2.imshow("otsu", binary_otsu)
cv2.waitKey()

# ret/ret1是一个浮点数，表示图像中像素值的阈值
print(ret)
print(ret1)
'''

'''
# 图像的形态学算法（腐蚀和膨胀）
import cv2
import numpy as np

# 在腐蚀和膨胀之前需要先将图片二值化
gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE)

_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)  # 使用反向阈值——背景白色，图案黑色
kernel = np.ones((5, 5), np.uint8)  # 操作需要用到的kernel

# 腐蚀和膨胀操作
erosion = cv2.erode(binary, kernel)
dilation = cv2.dilate(binary, kernel)

cv2.imshow("binary", binary)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)


cv2.waitKey()
'''


'''
# opencv调用电脑中的摄像头
import cv2

# 获取摄像头设备的指针(设备管理器 -> 照相机)
capture = cv2.VideoCapture(0)
ret = True

# 摄像头的读取是连续不断的，需要循环读取
while ret:
    ret, frame = capture.read()
    
    #ret：这是一个布尔值，表示读取操作是否成功。
    #如果 ret 为 True，表示成功读取了一帧图像；如果为 False，则表示读取失败，可能是因为视频流结束或者其他错误。
    #在处理视频流时，这个返回值通常用于控制循环，直到视频流结束。

    #frame：这是一个NumPy数组，代表了从视频捕获对象读取的当前帧。
    #这个数组通常是一个三维的，其形状为 (高度, 宽度, 通道数)，其中通道数可以是1（灰度图像）或3（彩色图像，分别对应红、绿、蓝通道）。
    
    cv2.imshow("camera", frame)
    key = cv2.waitKey(1)  # 等待键盘输入1ms
    if key != -1:  # 按任意键跳出循环
        break

capture.release()  # 释放指针
'''

import cv2
import numpy as np

def is_same_photo(image_1,image_2,threshold=10):
    gray1 = cv2.cvtColor(image_1,cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(image_2,cv2.COLOR_BGR2GRAY)
    result = cv2.subtract(gray1,gray2)
    non_zero_count = cv2.countNonZero(result) #计算非0像素的数量
    return non_zero_count <= threshold #与阈值相比较
#创建一个存储各个模板路径的字符串列表
strlist = ['D:/code/python/Template/0.png',
           'D:/code/python/Template/1.png',
           'D:/code/python/Template/2.png',
           'D:/code/python/Template/3.png',
           'D:/code/python/Template/4.png']
#存储各个模板，为了后续匹配且数组下标与内容匹配。
template = list()
for str in strlist:
    image = cv2.imread(str)
    #tmp = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    template.append(image)
#测试是否能匹配3
targe = cv2.imread('D:/code/python/Template/1.png')
# = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# 使用标准相关匹配算法——将待检测对象和模板都标准化再来计算匹配度
ans = 0
for i in range(0,len(template)):
    if is_same_photo(targe,template[i]):
        ans = i
        break
print(ans)

'''
import cv2

# 创建 windows 窗体
cv2.namedWindow("Real-time Screen Capture", cv2.WINDOW_NORMAL)

# 将 BGR 转换为 RGB (OpenCV 默认使用 RGB)
screenshot_np = cv2.cvtColor(screenshot_np, cv2.COLOR_BGR2RGB)
cv2.imshow("Real-time Screen Capture", screenshot_np)

'''